import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * @author Nizar
 *
 */

public class Parser {

	private Tokenizer t;
	private FileReader in;
	private Token token; 

	public Parser(String nomeFile) throws IOException {
		in = new FileReader(nomeFile);
		t = new Tokenizer(in);
		nextToken();
		parse();
	}
	
	public Expr parse() throws IOException{
		ExprSeq expr = null;
		while(t.next().getType() != Token.Type.EOS){
			expr= sequenceExpression();
		}
		return expr;
	}

	private ExprSeq sequenceExpression() throws IOException {
		List<Expr> expr = new ArrayList<Expr>();

		while(tokenType() == Token.Type.SEMICOLON)
			nextToken();
		expr.add(assignExpr());
		return null;
	}

	private Expr assignExpr() throws IOException {
		while(tokenType() != Token.Type.SEMICOLON || 
				tokenType() != Token.Type.CLOSEPAR || 
				tokenType() != Token.Type.EOS) {
			if(tokenType() == Token.Type.ID) {
				String idTemp = token().getName();
				nextToken();
				if(tokenType()==Token.Type.BECOMES){
					nextToken();
					if(tokenType()==Token.Type.NUM){
						AssignExpr assExpr = new AssignExpr(new Id(idTemp), new Num(token().getNum()));
						System.out.println(assExpr);
						return assExpr;
					}
					else{
						addExpr();
					}

				}
			}
		}
		return null;
	}

	private Expr addExpr() throws IOException {
		Expr left = null;
		Expr right = null;
		if(tokenType() == Token.Type.ID){
			left = new Id(token.getName());
			nextToken();
			if(tokenType() == Token.Type.PLUS){
				nextToken();
				if(tokenType() == Token.Type.NUM){
					right = new Num(token().getNum());
					return new PlusBinExpr(left, right);
				}else if(tokenType() == Token.Type.ID){
					right = new Id(token().getName());
					return new PlusBinExpr(left, right);
				}
			}

		}
		return right;

	}

	private Token.Type tokenType(){
		return token().getType();
	}

	private Token nextToken() throws IOException{
		token =t.next();
		return token;
	}

	private Token token(){
		return token;
	}

}
